package com.laolang.pluto.module.sys.logic.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.laolang.pluto.common.consts.GlobalConst;
import com.laolang.pluto.common.core.domain.common.Page;
import com.laolang.pluto.common.logic.impl.BaseLogicImpl;
import com.laolang.pluto.common.persist.entity.BaseEntity;
import com.laolang.pluto.common.util.AssertUtil;
import com.laolang.pluto.module.sys.consts.entity.SysTenantConst;
import com.laolang.pluto.module.sys.consts.entity.SysUserConst;
import com.laolang.pluto.module.sys.consts.logic.SysBizCode;
import com.laolang.pluto.module.sys.entity.SysTenant;
import com.laolang.pluto.module.sys.entity.SysUser;
import com.laolang.pluto.module.sys.logic.SysUserLogic;
import com.laolang.pluto.module.sys.pojo.dto.SysUserEditDto;
import com.laolang.pluto.module.sys.pojo.dto.SysUserListDto;
import com.laolang.pluto.module.sys.pojo.vo.SysUserVo;
import com.laolang.pluto.module.sys.service.SysTenantService;
import com.laolang.pluto.module.sys.service.SysUserService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author laolang
 * @date 2021-08-14 19:19
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserLogicImpl extends BaseLogicImpl implements SysUserLogic {

    private final SysUserService sysUserService;
    private final SysTenantService sysTenantService;


    @Override
    public Page<SysUserVo> list(SysUserListDto dto) {
        return pageInfo2Page(sysUserService.listUserInfo(dto.getPage(), dto.getSize(), dto.getUsername(),
                dto.getProjectId()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysUserVo add(SysUserEditDto dto) {
        assertSysTenantExist(dto.getUsername());
        assertUsernameExist(dto.getUsername(), null);
        SysTenant sysTenant = addSysTenant(dto.getUsername());
        SysUser insert = new SysUser();
        insert.setTenantId(sysTenant.getId());
        insert.setUsername(dto.getUsername());
        insert.setNickname(dto.getNickname());
        insert.setPassword("123456");
        insert.setStatus(SysUserConst.Status.NORMAL.getValue());
        insert.setType(SysUserConst.Type.TENANT_MASTER.getValue());
        insert.setCreateBy(GlobalConst.ADMIN_ID);
        sysUserService.save(insert);
        SysUserVo vo = new SysUserVo();
        PageInfo<SysUserVo> page = sysUserService.listUserInfo(1, 1, dto.getUsername(), null);
        if(CollUtil.isNotEmpty(page.getList())){
            vo = page.getList().get(0);
        }
        return vo;
    }

    private SysTenant addSysTenant(String code){
        SysTenant insert = new SysTenant();
        insert.setName(code);
        insert.setCode(code);
        insert.setStatus(SysTenantConst.Status.NORMAL.getValue());
        insert.setCreateBy(GlobalConst.ADMIN_ID);
        sysTenantService.save(insert);
        return insert;
    }


    @Override
    public SysUserVo edit(SysUserEditDto dto) {
        return null;
    }

    private SysTenant assertSysTenantExist(String code) {
        LambdaQueryWrapper<SysTenant> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysTenant::getCode, code);
        SysTenant sysTenant = sysTenantService.getOne(wrapper);
        return AssertUtil.isNull(log, sysTenant, SysBizCode.TENANT_NAME_EXIST, StrUtil.format("租户名已存在:{}", code));
    }

    private SysUser assertUsernameExist(String username, Long userId) {
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysUser::getUsername, username);
        wrapper.eq(SysUser::getStatus, SysUserConst.Status.NORMAL.getValue());
        if (null != userId) {
            wrapper.ne(BaseEntity::getId, userId);
        }
        SysUser sysUser = sysUserService.getOne(wrapper);
        return AssertUtil.isNull(log, sysUser, SysBizCode.USER_NAME_EXIST, StrUtil.format("用户名已存在:{}", username));
    }

}
